package com.diver.flinkdemo.service;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.diver.flinkdemo.entity.DalData;
import com.diver.flinkdemo.entity.xxt.Fence;
import com.diver.flinkdemo.entity.xxt.LocationInfo;
import com.diver.flinkdemo.entity.xxt.PolygonFence;
import com.diver.flinkdemo.entity.xxt.TerminalUnit;
import com.diver.flinkdemo.enums.MessageEnum;
import com.diver.flinkdemo.enums.StuCardTypeEnum;
import com.diver.flinkdemo.mapper.mysqlMapper.TerminalUnitMapper;
import com.diver.flinkdemo.service.impl.*;
import com.diver.flinkdemo.utils.CommonResource;
import com.diver.flinkdemo.utils.GaoDeMapUtil;
import com.diver.flinkdemo.utils.ObjectUtils;
import com.diver.flinkdemo.utils.RangeCompareUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author LuJW
 * @date 2023/5/11 15:05
 */
@Slf4j
public class LocationInfoHandleService {

    private ITerminalUnitService terminalUnitService = new TerminalUnitServiceImpl();
    private IRedisService redisService = new RedisServiceImpl();
    private IPolygonFenceService polygonFenceService = new PolygonFenceServiceImpl();
    private IFenceService fenceService = new FenceServiceImpl();
    private IPersonTerminalInfoService personTerminalInfoService = new IPersonTerminalInfoServiceImpl();

    public LocationInfo getLocation(LocationInfo locationInfo, DalData dalData) throws InvocationTargetException, IllegalAccessException {

        if (null == dalData) {
            log.info("dalData null...");
            return null;
        }
        String type = dalData.getType();
        //先复制共有字段
        BeanUtils.copyProperties(locationInfo,dalData);
        log.info("copyProperties-dalData: {}",dalData);
        log.info("copyProperties-locationInfo: {}",locationInfo);
        if (StringUtils.isNotBlank(locationInfo.getTypeIdent()) && "HEARTBEAT".equals(locationInfo.getTypeIdent())) {
            //设置驻网状态
            locationInfo.setNetStatus(dalData.getNetStatus());
        }
//        locationInfo.setStamp(String.valueOf(locationInfo.getUploadTime().getTime() / 1000));
        locationInfo.setPdop(dalData.getPdop());//定位精度
        locationInfo.setLat(dalData.getLatitude());
        locationInfo.setLon(dalData.getLongitude());
        locationInfo.setCreateTime(new Date());
        locationInfo.setWifi(dalData.getMac());
        locationInfo.setElectricity(dalData.getPower());
        locationInfo.setMac(dalData.getUploadType());
        locationInfo.setStep(dalData.getSteps());
        String typeIdent = dalData.getTypeIdent();

        if ("AL".equals(typeIdent) || "AL_SOS".equals(typeIdent)) {
            locationInfo.setExceptionMsg(MessageEnum.SOS.getDesc());
        }
        if (StringUtils.isNotBlank(locationInfo.getLat()) && StringUtils.isNotBlank(locationInfo.getLon())) {
            String address = getAddress(locationInfo.getLon(), locationInfo.getLat(), locationInfo.getAddress());
            locationInfo.setAddress(address);
        }
        TerminalUnit terminalUnit = terminalUnitService.getOneByCardNum(dalData.getImei(),11);
        if (terminalUnit == null) {
            log.info("未查询到该设备，{}",dalData.getImei());
            return null;
        }else {
            terminalUnitService.updateLastUploadTime(dalData.getImei(),locationInfo.getUploadTime());
            log.info("terminalUnit表最新更新时间：cardNum: {}, uploadTime: {}",dalData.getImei(),locationInfo.getUploadTime());
        }
        if ("PARSED_LOCATION".equals(dalData.getType())) {
            if (CommonResource.CARDVERSION_XYZJ.equals(terminalUnit.getDistributionChannel())) {//晓羊平台推送
                Integer isSafety = locationInfo.getIsSafety() == null ? 0 : locationInfo.getIsSafety();
                String stuId = locationInfo.getImei();
                String personId = personTerminalInfoService.getBindPersonId(stuId);
                log.info("setXyFenceInfo===>{}, isInFence:{}", stuId, isSafety);
                String key = CommonResource.XY_POLYGON_FENCE_LIST + "_" + stuId;
                List<Fence> fenceList = redisService.getList(key, Fence.class);
                if (fenceList == null && fenceList.isEmpty()) {
                    log.info("get xyFenceList from businessClient {}", stuId);
                    fenceList = fenceService.getFenceByPersonId(stuId);
                    redisService.set(key, fenceList);
                }
                if (fenceList != null || !fenceList.isEmpty()) {
                    for (Fence fence : fenceList) {
                        // 1 在围栏内
                        // 0 在围栏外
                        int inFence = RangeCompareUtil.calculatePoint(locationInfo.getLon(), locationInfo.getLat(), fence.getPolygonList());
                        if (1 == inFence) {
                            locationInfo.setIsSafety(inFence);
                            locationInfo.setFenceId(fence.getId());
                            locationInfo.setExceptionMsg("在" + fence.getFenceName() + "(小羊)附近");
                        }
                    }
                }
            }else if (CommonResource.CARDVERSION_XXT.equals(terminalUnit.getDistributionChannel())
                    || CommonResource.CARDVERSION_SCHJY.equals(terminalUnit.getDistributionChannel())
                    || CommonResource.CARDVERSION_TLJY.equals(terminalUnit.getDistributionChannel())) {

                String personId = personTerminalInfoService.getBindPersonId(terminalUnit.getCardNum());
                Integer isSafety = locationInfo.getIsSafety();
                if (null == isSafety) {
                    locationInfo.setIsSafety(0);
                    String cardType = terminalUnit.getTerminalSeries();
                    if (StuCardTypeEnum.XTC0.getType().equals(cardType) || StuCardTypeEnum.XTC1.getType().equals(cardType) || StuCardTypeEnum.XTC40.getType().equals(cardType)|| StuCardTypeEnum.XTC2.getType().equals(cardType)) {
                        List<Fence> fenceList = getSecurityAreas(personId);
                        if (fenceList!=null && !fenceList.isEmpty()) {
                            for (Fence sa : fenceList) {
                                double distance = ObjectUtils.getDistanceMeter(sa.getCircleLat(), sa.getCircleLon(), locationInfo.getLat(), locationInfo.getLon());
                                BigDecimal dt = new BigDecimal(distance), radius = new BigDecimal(sa.getCircleRadius());
                                if (dt.compareTo(radius) <= 0) {
                                    locationInfo.setIsSafety(1);
                                    locationInfo.setExceptionMsg("在" + sa.getFenceName() + "附近");
                                    locationInfo.setFenceId(sa.getId());
                                }
                            }
                        }
                    }
                } else if (1 == isSafety && StringUtils.isNotBlank(locationInfo.getSafetyName())) {//处理在除 异常信息以外 “在**附近”提示（是否在安全区域内提示）
                    locationInfo.setExceptionMsg("在" + locationInfo.getSafetyName() + "附近");
                }
            }
        }

        return locationInfo;
    }

    private String getAddress(String lng, String lat, String address) {
        if (StringUtils.isBlank(address)) {
            if ((StringUtils.isNotBlank(lat) && !"0".equals(lat)) && (StringUtils.isNotBlank(lng) && !"0".equals(lng))) {
                address = GaoDeMapUtil.getAddressByLonLat(lng, lat);
            }
        }
        return address;
    }


    protected List<Fence> getSecurityAreas(String personId) {
        String key = CommonResource.SECURITY_AREA_LIST + "_" + personId;
        List<Fence> fenceList = redisService.getList(key, Fence.class);
        if (fenceList == null || fenceList.isEmpty()) {
            log.info("get securityAreas from businessClient {}", personId);
            fenceList = fenceService.getFenceByPersonId(personId);
//            securityAreas = securityAreaService.getAreaByStudentCardId(stuId);
//            redisService.set(key, securityAreas);
            redisService.set(key, fenceList);
        }
        return fenceList;
    }
}
